home *** CD-ROM | disk | FTP | other *** search
Wrap
//============================================================================== // Scn04p2: AI Scenario Script for scenario 4 player 2 //============================================================================== /* AI owner: Dave Leary Scenario owner: Dave Leary This AI transports existing units to the mainland. The player defends against waves of attacks from the water consisting of pirate ships and krakens. The pirate ships should drop off several waves of land attackers (axemen mostly, one wave of slingers and anubites, and one scorpion man in the last group of axemen). Most of the scenario is handled via trigger, but the three landings are handled by a transport plan that is called with an AI Func (see "attackLauncher" below). Each wave is triggered by the destruction of the primary boat or kraken from the previous wave. *** DIFFICULTY LEVEL NOTES *** Easy level - Additional resources provided. Player starts with four extra toxotes. Attack groups slightly reduced (no anubites). Moderate level - Base level. No modifiers. Difficult level - Shore towers and armory removed. Nightmare - Shore towers and armory removed. Many starting toxotes deleted. Additional "rearguard" Atlantis towers deleted. Starting resources seriously reduced. */ //============================================================================== // Set Town Location //============================================================================== void setTownLocation(void) { //Look for the "Town Location" marker. kbSetTownLocation(kbGetBlockPosition("2639")); } //============================================================================== // miscStartup //============================================================================== void miscStartup(void) { // Difficulty Level check. int difflevel=-1; difflevel=aiGetWorldDifficulty(); //Startup message(s). aiEcho(""); aiEcho(""); aiEcho("Scn04P2 AI Start, filename='"+cFilename+"'."); aiEcho("Difficulty Level="+difflevel+"."); //Spit out the map size. aiEcho(" Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+")."); //Cheat like a bastard. Once only, though. kbLookAtAllUnitsOnMap(); //Calculate some areas. kbAreaCalculate(1200.0); //Set our town location. setTownLocation(); //Reset random seed aiRandSetSeed(); //Allocate all resources to the root escrow. kbEscrowAllocateCurrentResources(); } //============================================================================== //============================================================================== // Attack stuff. //============================================================================== //============================================================================== //Shared variables. int attackerUnitTypeIDSoldier=cUnitTypeAxeman; int attackerUnitTypeIDTransport=cUnitTypePirateShip; //========================================================================================= // Kidd's cool configQuery function: used to create attack routes, etc. Oooh, lovin' that! //========================================================================================= bool configQuery( int queryID = -1, int unitType = -1, int action = -1, int state = -1, int player = -1, vector center = vector(-1,-1,-1), bool sort = false, float radius = -1 ) { if ( queryID == -1) { return(false); } if (player != -1) kbUnitQuerySetPlayerID(queryID, player); if (unitType != -1) kbUnitQuerySetUnitType(queryID, unitType); if (action != -1) kbUnitQuerySetActionType(queryID, action); if (state != -1) kbUnitQuerySetState(queryID, state); if (center != vector(-1,-1,-1)) { kbUnitQuerySetPosition(queryID, center); if (sort == true) kbUnitQuerySetAscendingSort(queryID, true); if (radius != -1) kbUnitQuerySetMaximumDistance(queryID, radius); } return(true); } //===================================================================================== // Attack Launcher. This is called from the scenario with an AI Func effect //===================================================================================== void attackLauncher(int whichAttack = -1) { int transportPlanID=aiPlanCreate("Transport Group", cPlanTransport); // "whichTransport" adds a specific transport to the plans. Victory conditions, chats, etc. // are tied to the concept of the main transport getting whacked. int whichTransport=-1; // Difficulty Level check. int difflevel=-1; difflevel=aiGetWorldDifficulty(); vector gatherPoint=kbGetBlockPosition("2638"); vector targetPoint=kbGetBlockPosition("2642"); vector initialPosition=kbGetBlockPosition("2639"); int baseID = kbBaseCreate( 2, "mainBase", initialPosition, 50.0); if (transportPlanID >= 0) { aiEcho("*** ATTACK LAUNCHER SENDING TRANSPORT ***"); // Different composition depending on which attack. switch(whichAttack) { case 0: { whichTransport = kbGetBlockID("2632"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 5, 5, 5); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 1: { whichTransport = kbGetBlockID("2637"); gatherPoint=kbGetBlockPosition("2640"); targetPoint=kbGetBlockPosition("2643"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 5, 5, 5); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 2: { whichTransport = kbGetBlockID("2633"); gatherPoint=kbGetBlockPosition("2658"); targetPoint=kbGetBlockPosition("2641"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 6, 6, 6); if ( difflevel > 0 ) { aiPlanAddUnitType(transportPlanID, cUnitTypeSlinger, 2, 2, 2); } aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 3: { whichTransport = kbGetBlockID("2788"); gatherPoint=kbGetBlockPosition("2640"); targetPoint=kbGetBlockPosition("2641"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeSlinger, 6, 6, 6); if ( difflevel > 0 ) { aiPlanAddUnitType(transportPlanID, cUnitTypeAnubite, 2, 2, 2); } aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 4: { whichTransport = kbGetBlockID("2634"); gatherPoint=kbGetBlockPosition("2639"); targetPoint=kbGetBlockPosition("2785"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 7, 7, 7); aiPlanAddUnitType(transportPlanID, cUnitTypeScorpionMan, 1, 1, 1); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } } aiPlanSetVariableBool(transportPlanID, cTransportPlanMaximizeXportMovement, 0, true); aiPlanSetVariableVector(transportPlanID, cTransportPlanGatherPoint, 0, gatherPoint); aiPlanSetVariableVector(transportPlanID, cTransportPlanTargetPoint, 0, targetPoint); // Setting the base. aiPlanSetBaseID( transportPlanID, baseID ); // Don't return when finished. aiPlanSetVariableBool(transportPlanID, cTransportPlanReturnWhenDone, 0, false); // Initial Position aiPlanSetInitialPosition( transportPlanID, initialPosition ); aiPlanAddUnit(transportPlanID, whichTransport); aiPlanSetActive(transportPlanID); } } //============================================================================== // initAttack: Creates attack routes, etc. //============================================================================== /* void initAttack(int playerID=-1) { //Destroy all previous attacks (if this isn't the player we're already attacking. if (playerID != attackPlayerID) { //Reset the attack player ID. attackPlayerID=-1; //Destroy any previous attack plan. aiPlanDestroy(attackPlan1ID); attackPlan1ID=-1; aiPlanDestroy(attackPlan2ID); attackPlan2ID=-1; //Destroy our previous attack paths. kbPathDestroy(attackPath1ID); attackPath1ID=-1; kbPathDestroy(attackPath2ID); attackPath2ID=-1; //Destroy our previous attack routes. attackRoute1ID=-1; attackRoute2ID=-1; //Reset the number of attacks. numberAttacks=0; } //Save the player to attack. attackPlayerID=playerID; vector gatherPoint=kbGetBlockPosition("3989"); //Setup attack path 1 - go left attackPath1ID=kbPathCreate("Attack Path 1"); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3990")); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3991")); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3992")); //Create attack route 1. attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("3995")); if (attackRoute1ID >= 0) kbAttackRouteAddPath(attackRoute1ID, attackPath1ID); //Setup attack path 2 - go right attackPath2ID=kbPathCreate("Attack Path 2"); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3990")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3991")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3993")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3994")); //Create attack route 2. attackRoute2ID=kbCreateAttackRouteWithPath("Attack Route 2", gatherPoint, kbGetBlockPosition("3995")); if (attackRoute2ID >= 0) kbAttackRouteAddPath(attackRoute2ID, attackPath2ID); } */ //============================================================================== // setupAttack //============================================================================== /* bool setupAttack(int playerID=-1) { int randomPath=aiRandInt(2); //Info. aiEcho("Attacking Player "+playerID+"."); //If the player to attack doesn't match, init the attack. if (attackPlayerID != playerID) { initAttack(playerID); if (attackPlayerID < 0) return(false); } //Create an attack plan. int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack); if (newAttackPlanID < 0) return(false); //Target player (required). This must work. if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false) return(false); //Gather point. vector gatherPoint=kbGetBlockPosition("3989"); //Set the target type. This must work. if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false) return(false); //Unit types to attack. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit); aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding); //Attack route. if (randomPath == 0) { aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID); } else { aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute2ID); } //Set the gather point and gather point distance. aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint); aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 10.0); //Set up the attack route usage pattern. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom); //Add the unit types to the plan. aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, attackMinimumGroupSize, attackMaximumGroupSize, attackMaximumGroupSize); //Set the initial position. aiPlanSetInitialPosition(newAttackPlanID, gatherPoint); //Plan requires all need units to work (can be false). aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true); //Activate the plan. aiPlanSetActive(newAttackPlanID); //Now, save the attack plan ID appropriately. aiPlanSetOrphan(attackPlan1ID, true); attackPlan1ID=newAttackPlanID; //Increment our overall number of attacks. numberAttacks++; } */ //============================================================================== // Attack Generator 1 - Axemen and friends //============================================================================== /* rule attackGenerator1 minInterval 75 inactive group AttackRules runImmediately { //See how many "idle" attack plans we have. Don't create any more if we have //idle plans. int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack); if (numberIdleAttackPlans > 0) return; //If we have enough unassigned military units, create a new attack plan. int numberAvailableUnits=aiNumberUnassignedUnits(attackerUnitTypeID1); aiEcho("There are "+numberAvailableUnits+" axemen available for a new attack."); if (numberAvailableUnits >= attackMinimumGroupSize) setupAttack(1); } */ //============================================================================== // Attack enablers - enable attacks after initial timers expire //============================================================================== /* // Axemen rule attack1Enabler minInterval 240 active group AttackRules { xsEnableRule("attackGenerator1"); xsDisableSelf(); } */ //============================================================================== // Tech Researching Rules - medium axemen, medium slingers, medium spearmen //============================================================================== /* rule researchMediumAxemen minInterval 600 active { int planID=aiPlanCreate("Medium Axemen research at ten minutes.", cPlanResearch); if (planID < 0) return; aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechMediumAxemen); aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeBarracks); aiPlanSetActive(planID); //Done. xsDisableSelf(); } */ //============================================================================== // MAIN. //============================================================================== void main(void) { //Startup. miscStartup(); }